package db

import (
	"errors"
	"time"

	"gitee.com/huangxinbo/xcas/internal/config"
	"gitee.com/huangxinbo/xcas/pkg/logger"
	"gorm.io/driver/postgres"
	"gorm.io/gorm"
)

func NewDB(config *config.Config, logger *logger.Logger) (*gorm.DB, error) {
	if config.DB.DSN == "" {
		return nil, errors.New("DB.DSN is empty")
	}
	opts := &gorm.Config{}

	gormLogger, err := NewLogger(logger, config.DB.EnableSQLLog)
	if err != nil {
		return nil, err
	}

	opts.Logger = gormLogger

	db, err := gorm.Open(postgres.New(postgres.Config{
		DSN: config.DB.DSN,
	}), opts)

	if err != nil {
		return nil, err
	}

	sqlDB, err := db.DB()
	if err != nil {
		return nil, err
	}

	// Set connection pool parameters
	// Configuration suggestions, final configuration should be based on actual scenarios
	// Low traffic applications: MaxIdleConns=10, MaxOpenConns=50
	// High concurrency applications: MaxIdleConns=25, MaxOpenConns=100-200
	sqlDB.SetMaxIdleConns(config.DB.ConnMaxIdleTime)                                 // Maximum 25 idle connections in the pool
	sqlDB.SetMaxOpenConns(config.DB.MaxIdleConns)                                    // Maximum 100 concurrent connections
	sqlDB.SetConnMaxLifetime(time.Duration(config.DB.ConnMaxLifetime) * time.Minute) // Connection maximum lifetime 30 minutes, will be forcibly closed after this time
	sqlDB.SetConnMaxIdleTime(time.Duration(config.DB.ConnMaxIdleTime) * time.Minute) // Idle connections maximum lifetime 5 minutes, will be closed after this time
	return db, nil
}
